package com.alogic.metrics.stream;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang3.StringUtils;

import com.alogic.metrics.Dimensions;
import com.alogic.metrics.Fragment;
import com.alogic.metrics.Measures;
import com.alogic.metrics.Value;
import com.anysoft.util.Pair;

/**
 * Prometheus指标输出
 * 
 * @author duanyy
 * @since 1.6.12.29 [20190409] <br>
 *
 * @version 1.6.12.30 [20190425 duanyy] <br>
 * - 指标输出增加转义 <br>
 */
public class PrometheusMetricsCollector implements MetricsCollector{

	protected StringBuffer buffer = null;
	protected String staticLables = "a=a";
	public PrometheusMetricsCollector(StringBuffer buf,String staticLabels){
		this.buffer = buf;
		this.staticLables = StringUtils.isNotEmpty(staticLabels)?staticLabels:this.staticLables;
	}
	
	@Override
	public void metricsIncr(Fragment f) {
		Dimensions dims = f.getDimensions();
		
		StringBuffer labels = new StringBuffer();
		
		labels.append("{").append(staticLables);
		
		List<Pair<String,String>> result = new ArrayList<Pair<String,String>>();
		dims.listEntries(result);
		if (!result.isEmpty()){			
			for (Pair<String,String> pair:result){
				labels.append(",").append(pair.key()).append("=\"");
				writeEscapedLabelValue(labels,pair.value());
				labels.append("\"");
			}			
		}
		labels.append("}");
		
		Measures measures = f.getMeasures();
		Value[] values = measures.values();
		for (Value value:values){
			String metricsName = getMetricsName(f.id(),value.key());
			buffer.append(metricsName);
			buffer.append(labels);
			buffer.append(" ");
			switch (value.type()){
			case D:
				buffer.append(value.asDouble(0.0d));
				break;
			case L:
				buffer.append(value.asLong(0));
				break;
			default:
				buffer.append(value.asString("NaN"));
			}
			
			buffer.append("\n");
		}
	}
	
	public String getMetricsName(String id,String measureId){
		String name = String.format("alogic_%s_%s", id,measureId);
		return name.replace(".", "_");
	}

	private static void writeEscapedLabelValue(StringBuffer writer, String s) {
		for (int i = 0; i < s.length(); i++) {
			char c = s.charAt(i);
			switch (c) {
			case '\\':
				writer.append("\\\\");
				break;
			case '\"':
				writer.append("\\\"");
				break;
			case '\n':
				writer.append("\\n");
				break;
			default:
				writer.append(c);
			}
		}
	}
}
